﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection.Emit;
using System.Text;
using System.Threading.Tasks;
using bitzhuwei.Compiler;

namespace bitzhuwei.ExpFormat {
    /// <summary>
    /// Correspond to the Vn node Term in the grammar(Exp).
    /// </summary>
    internal partial class VnTerm : IVnNode {
        // [3]=Term : Term '*' Factor ;
        // [4]=Term : Term '/' Factor ;
        // [5]=Term : Factor ;

        private readonly VnFactor first0;
        public class PostItem : IVnNode {
            private readonly Token r1;
            private readonly VnFactor r0;

            public PostItem(Token r1, VnFactor r0) {
                this.r1 = r1;
                this.r0 = r0; r0.Parent = this;
                this._scope = new TokenRange(r1, r0);
            }
            public IInherit? Parent { get; set; }

            private readonly TokenRange _scope;
            public TokenRange Scope => _scope;

            public void FullFormat(BlankConfig preConfig, TextWriter writer, FormatContext context) {
                context.PrintBlanksAnd(this.r1, preConfig, writer);
                // '+'或'-'与其左右两边的Token间隔1个空格
                var config = new BlankConfig(inlineBlank: 1, forceNewline: false);
                context.PrintCommentsBetween(this.r1, this.r0, config, writer);
                context.PrintBlanksAnd(this.r0, config, writer);
            }

            public IEnumerable<IInherit> ReversedChildren() {
                yield return this.r0;
                var wrap = new IInherit.TokenWrap(r1);
                wrap.Parent = this;
                yield return wrap;
            }
            public void PrintSelf(TextWriter writer, IReadOnlyList<string>? stArray) {
                writer.Write($"Item T[{_scope}]");
            }
            public override string ToString() {
                return $"Item T[{_scope}]";
            }

        }
        private PostItemList? list;

        private readonly TokenRange _scope;
        public TokenRange Scope => _scope;

        // [5]=Term : Factor ;
        // dumped by ListExtractor 1
        internal VnTerm(VnFactor first0) {
            this.first0 = first0; first0.Parent = this;
            this._scope = new TokenRange(first0);
        }

        // [3]=Term : Term '*' Factor ;
        // [4]=Term : Term '/' Factor ;
        // dumped by ListExtractor 2
        internal void Add(
            Token r1/* reserved word is omissible */
            , VnFactor r0
        ) {
            if (this.list == null) {
                this.list = new PostItemList(new PostItem(r1, r0));
                this.list.Parent = this;
            }
            else {
                this.list.Add(new PostItem(r1, r0));
            }
            this._scope.end = this.list.Scope.end;
        }

        public void FullFormat(BlankConfig preConfig, TextWriter writer, FormatContext context) {
            context.PrintBlanksAnd(this.first0, preConfig, writer);
            if (this.list != null) {
                // '*'或'/'与其左右两边的Token间隔1个空格
                var config = new BlankConfig(inlineBlank: 1, forceNewline: false);
                context.PrintCommentsBetween(this.first0, this.list, config, writer);
                context.PrintBlanksAnd(this.list, config, writer);
            }
        }

        public IInherit? Parent { get; set; }

        public IEnumerable<IInherit> ReversedChildren() {
            if (this.list != null) { yield return this.list; }
            yield return this.first0;
        }
        public void PrintSelf(TextWriter writer, IReadOnlyList<string>? stArray) {
            writer.Write($"{nameof(VnTerm)}⛪T[{this.Scope}]");
        }
        public override string ToString() {
            return $"{nameof(VnTerm)}⛪T[{this.Scope}]";
        }
    }
}
